package 每日一题;

/**
 * 42. 接雨水
 * 困难
 * 相关标签
 * 相关企业
 * 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。
 *
 *
 *
 * 示例 1：
 *
 *
 *
 * 输入：height = [0,1,0,2,1,0,1,3,2,1,2,1]
 * 输出：6
 * 解释：上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图，在这种情况下，可以接 6 个单位的雨水（蓝色部分表示雨水）。
 * 示例 2：
 *
 * 输入：height = [4,2,0,3,2,5]
 * 输出：9
 *
 *
 * 提示：
 *
 * n == height.length
 * 1 <= n <= 2 * 104
 * 0 <= height[i] <= 105
 */
public class T042_接雨水 {

    public int trap(int[] height) {

        if (height.length<=2){
            return 0;
        }

//        使用两个数组 分别记录 每个位置 左侧的最大值 和右侧的最大值

        int[] left = new int[height.length];
        int[] right = new int[height.length];

        //left
        int leftMax = height[0];
        for (int i = 1; i < height.length; i++) {
            leftMax = Math.max(leftMax, height[i-1]);
            left[i] = leftMax;
        }

        int rightMax = height[height.length-1];
        for (int i = height.length-2; i >= 0; i--) {
            rightMax = Math.max(rightMax, height[i+1]);
            right[i] = rightMax;
        }

        //开始统计每列能接的雨水
        int count = 0;
        for (int i = 0; i < height.length-1; i++) {

            leftMax = left[i];
            rightMax = right[i];

            //左侧没墙 或者右侧没墙
            if (leftMax<=0||rightMax<=0){
                continue;
            }

            //当前列的墙高 高于两边的最高的墙 没法存水
            if (height[i]>=leftMax||height[i]>=rightMax){
                continue;
            }

            //木桶原理 低的一侧决定水的高度 减去墙的高度 就是当前列存水的高度
            count += (Math.min(leftMax,rightMax) - height[i]);

        }

        return count;
    }

}
